#! /usr/bin/env python
# -*- coding: utf-8 -*-

# Copyright (c) Huoty, All rights reserved
# Author: Huoty <sudohuoty@163.com>

__version__ = "0.0.1"

import os
import sys
import glob
import curses

# 查找下一个匹配项的函数
def search_next(lines, current_line, term):
    # Start searching from the line following the current one
    for i in range(current_line + 1, len(lines)):
        if term.lower() in lines[i].lower():
            return i
    return None

# 查找上一个匹配项的函数
def search_previous(lines, current_line, term):
    # Start searching backwards from the line before the current one
    for i in range(current_line - 1, -1, -1):
        if term.lower() in lines[i].lower():
            return i
    return None

# 高亮匹配文本的函数
def highlight_text(line, term, win, y, x):
    start = 0
    while start < len(line):
        found_at = line.lower().find(term.lower(), start)
        if found_at == -1:
            win.addstr(y, x+start, line[start:])
            break
        else:
            win.addstr(y, x+start, line[start:found_at])
            win.attron(curses.color_pair(1))  # 开启高亮颜色对
            win.addstr(y, x+found_at, line[found_at:found_at+len(term)])
            win.attroff(curses.color_pair(1))  # 关闭高亮颜色对
            start = found_at + len(term)

# 初始化界面
def init_screen(stdscr):
    curses.curs_set(0)  # 隐藏光标
    stdscr.keypad(True)  # 键盘特殊键位支持
    curses.start_color()  # 初始化颜色
    curses.init_pair(1, curses.COLOR_YELLOW, curses.COLOR_BLACK)  # 定义颜色对1为黄字黑底
    curses.noecho()  # 关闭回显
    curses.cbreak()  # 立即接收字符，无需等待Enter键

def main(stdscr, filename, lines):
    init_screen(stdscr)
    num_lines = len(lines)
    height, width = stdscr.getmaxyx()  # 获取窗口尺寸
    page_height = height - 1  # 留出一行用于用户输入
    current_line = 0
    last_search_term = ''

    # TODO: 滚动到底时避免重绘，否则会有屏闪

    while True:
        stdscr.clear()

        for i in range(page_height):
            if current_line + i < num_lines:
                to_print = lines[current_line + i]
                if last_search_term and last_search_term.lower() in to_print.lower():
                    highlight_text(to_print, last_search_term, stdscr, i, 0)
                else:
                    stdscr.addstr(i, 0, to_print[:width-1])

        stdscr.refresh()

        key = stdscr.getch()
        if key == ord('q'):  # 按q退出
            break
        elif key in (curses.KEY_DOWN, ord('j'), ord("\n")):  # 向下滚动
            if current_line < num_lines - page_height:
                current_line += 1
        elif key in (curses.KEY_UP, ord('k')):  # 向上滚动
            if current_line > 0:
                current_line -= 1
        elif key in (curses.KEY_NPAGE, ord(' ')):  # 下一页
            if current_line < num_lines - page_height:
                current_line = min(current_line + page_height, num_lines - page_height)
        elif key in (curses.KEY_PPAGE, ord('b')):  # 上一页
            if current_line > 0:
                current_line = max(current_line - page_height, 0)
        elif key == ord('/'):  # 进入搜索模式
            stdscr.addstr(height-1, 0, "/" + " " * (width-2))  # 清除最后一行
            stdscr.refresh()
            curses.echo()  # 开启回显获取搜索词
            stdscr.move(height-1, 1)  # 移动光标到"/"之后
            stdscr.refresh()
            last_search_term = stdscr.getstr().decode().strip()
            curses.noecho()  # 关闭回显
            next_line = search_next(lines, current_line, last_search_term)
            if next_line is not None:
                current_line = next_line
        elif key == ord('n') and last_search_term:  # 查找下一个匹配项
            next_line = search_next(lines, current_line, last_search_term)
            if next_line is not None:
                current_line = next_line  # 更新当前行为下一个匹配项
        elif key == ord('N') and last_search_term:  # 查找上一个匹配项
            prev_line = search_previous(lines, current_line, last_search_term)
            if prev_line is not None:
                current_line = prev_line  # 更新当前行为上一个匹配项

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: clib <sheet>", file=sys.stderr)
        sys.exit(1)

    userhome = os.getenv("HOME")
    currentdir = os.path.dirname(os.path.abspath(__file__))
    sheetdirs = [
        os.path.join(userhome, ".cribsheets"),
        os.path.join(userhome, ".local/cribsheets"),
        os.path.join(currentdir, "sheets"),
        os.path.join(currentdir, "cribsheets"),
        "/usr/local/share/cribsheets",
        "/usr/share/cribsheets",
    ]
    sheetname = sys.argv[1]
    sheetpath = None
    for sheetdir in sheetdirs:
        sheetpath = os.path.join(sheetdir, sheetname)
        if os.path.isfile(sheetpath):
            break
    else:
        print("No such cribsheet: {}".format(sheetname))
        sys.exit(1)

    try:
        with open(sheetpath, 'r') as f:
            lines = f.readlines()
    except IOError as e:
        print(f"Error opening file: {e}")
        sys.exit(1)

    # 启动curses应用
    curses.wrapper(main, sheetpath, lines)
